﻿#include"XQFtp.hpp"
#include"curl/curl.h"
#include<QFileInfo>
// 下载进度
static int DownProgressCallback(XQFtpFileTransferInfo* info, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
    XQFtpFileTransferInfo* LPinfo = info;
    LPinfo->curSize = dlnow;
    LPinfo->percent = (float)dlnow / dltotal;
    if (dlnow == 0)
        return 0;
    emit LPinfo->ftp->progress(*LPinfo);
    return 0;
}

// ---- 下载相关 ---- //
// 写数据上传
static size_t writeFunc(void* ptr, size_t size, size_t nmemb, void* stream)
{
    //std::cout << "--- write func ---" << std::endl;
    return fwrite(ptr, size, nmemb, (FILE*)stream);
}

int XQFtp::Download(const QString& local_file_path, const QString& remote_file_path)
{
    size_t fileSumSize=this->fileSize(remote_file_path);//文件总大小
    int tries = 3;
    curl_global_init(CURL_GLOBAL_ALL);//全局初始化
    CURL* curl=init();

    FILE* file =NULL;
    size_t fileSize = 0;//文件大小
    long downloaded_len = 0;//下载的文件长度
    CURLcode res = CURLE_GOT_NOTHING;
    int use_resume = 0; // 文件是否存在
    if (QFileInfo(local_file_path).exists())
    {
        use_resume = 1;//文件存在
        fileSize = QFileInfo(local_file_path).size();
        file = fopen(local_file_path.toLocal8Bit().data(), "ab");//文件存在以追加模式读写文件
    }
    else
    {
        file = fopen(local_file_path.toLocal8Bit().data(), "wb");//以创建模式写入
    }
    if (file == NULL)
    {
        perror(NULL);
        return 0;
    }

    //设置url
    QString url = setUrl(remote_file_path);
    curl_easy_setopt(curl, CURLOPT_URL, setUrl(remote_file_path).toLocal8Bit().data());
    // 设置连接超时时间
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, m_timeout);
    // 设置报头进程，获取内容长度回调
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, getContentLengthFunc);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &downloaded_len);

    // 断点续传 设置本地文件长度开启
    curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, use_resume ? fileSize : 0);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunc);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);

    // 设置下载进度
    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, DownProgressCallback);
    XQFtpFileTransferInfo info = {this,local_file_path,remote_file_path ,0,fileSumSize,0.0,tranType::down};
    emit start(info);
    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &info);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);


    //    curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1); //如果设置为1，调试模式将打印一些低级别的MSG

    res = curl_easy_perform(curl);
    fclose(file);
    emit finish(std::move(info));
    int curl_state = 0;
    if (res == CURLE_OK)
        curl_state = 1;
    else
    {
        fprintf(stderr, "%s\n", curl_easy_strerror(res));
        curl_state = 0;
    }

    // 退出清理
    curl_easy_cleanup(curl);
    curl_global_cleanup();

    return curl_state;
}

int XQFtp::Download()
{
    return Download(m_local_file_path, m_remote_file_path);
}
